package com.feidee.fd.sml.algorithm.component.validation.action
import com.feidee.fd.sml.algorithm.component.validation.ValidationParam
import com.feidee.fd.sml.algorithm.forecast.Forecast
import com.feidee.fd.sml.algorithm.util.HttpUtil
import com.feidee.fdcommon.constant.CommonConstant
import org.apache.spark.sql.DataFrame
import org.json4s.DefaultFormats
import org.json4s.jackson.Serialization.{read, write}

/**
  * @Author songhaicheng
  * @Date 2019/5/14 16:04
  * @Description
  * @Reviewer
  */
case class UpdateModelAction(
                              token: String,
                              modelPaths: Array[String],
                              modelTypes: String,
                              description: String,
                              poolSize: Int
                            ) extends Action {

  def this() = this(null, Array.empty[String], Forecast.MODEL_TYPE_SPARK, "none", 0)

  val envUrl: Map[String, String] = Map[String, String](
    CommonConstant.ENV_DEV -> "http://10.201.7.232:8063/sml/model/push",
    CommonConstant.ENV_TEST -> "http://10.201.7.239:8063/sml/model/push",
    CommonConstant.ENV_LIVE -> "http://sml.suishoudata.com/sml/model/push"
  )

  override def act(data: DataFrame, validationParam: ValidationParam): Boolean = {
    // 检验运行环境，用于确定像那个 url 发送更新模型请求
    if (envUrl.get(validationParam.env).isEmpty) {
      logError(s"检测运行环境失败，无法发送更新模型请求：未知环境：${validationParam.env}")
      return false
    }
    modelTypes.split(",").foreach(modelType => require(Forecast.SUPPORTED_MODEL_TYPES.contains(modelType.toLowerCase),
      s"param modelTypes only accepts [${Forecast.SUPPORTED_MODEL_TYPES.mkString(", ")}], but has $modelTypes"))

    var reqMap = Map[String, Any]()
    reqMap += ("token" -> token)
    // 自动加上时间戳信息
    reqMap += ("hdfsPath" ->
      ConvertModelTypeAction.modelPathTimeAppender(modelTypes, modelPaths, validationParam.flow_time).mkString(","))
    reqMap += ("modelTypes" -> modelTypes)
    reqMap += ("creator" -> validationParam.submitter)
    reqMap += ("source" -> s"Azkaban Job: ${validationParam.project_name}")
    reqMap += ("description" -> description)
    reqMap += ("online" -> true)
    reqMap += ("poolSize" -> poolSize)

    implicit val formats: DefaultFormats.type = DefaultFormats
    val body = write(reqMap)
    logInfo(s"posting to ${envUrl(validationParam.env)} with body: $body")

    val response = HttpUtil.postWithEncryption("/sml/model/push", envUrl(validationParam.env), body)
   // val resMsg = read[Map[String, Any]](response.getResponseBody)
   // val success = response.getStatusCode == 200 && resMsg("code") == 0 && resMsg("currentVersion").toString.toInt > 0
  /*  if (success) {
      logInfo(s"更新模型成功（with token ${reqMap("token").toString}）")
    } else {
      logError(s"更新模型失败：${response.getResponseBody}")
    }
    success*/
    true
  }
}
